package com.lzh.rocblogbackend.utils;

import com.lzh.rocblogbackend.mapper.BlogMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Component
public class RedisUtil {
    @Resource
    private RedisTemplate<String,Object> redisTemplate;
    @Autowired
    private BlogMapper blogMapper;
    /**
     * 判断key是否存在
     */
    public boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 删除Key
     */
    public void del(String... key) {
        if(key!=null&&key.length>0) {
            if(key.length==1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
            }
        }
    }
    /**
     * 获取Key
     */
    public Object get(String key) {
        return key==null?null:redisTemplate.opsForValue().get(key);
    }
    /**
     * 添加Key
     */
    public boolean set(String key,Object value) {
        try {
            redisTemplate.opsForValue().set(key,value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 添加Key并设置时间
     */
    public boolean set(String key,Object value,long time) {
        try {
            if(time>0) {
                redisTemplate.opsForValue().set(key,value,time, TimeUnit.SECONDS);
            } else {
                redisTemplate.opsForValue().set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * Value加
     */
    public long incr(String key,long val) {
        if(val<0) {
            throw new RuntimeException("加数不能小于0");
        }
        return redisTemplate.opsForValue().increment(key,val);
    }
    /**
     * Value减
     */
    public long decr(String key,long val) {
        if(val<0) {
            throw new RuntimeException("减数不能小于0");
        }
        return redisTemplate.opsForValue().increment(key,-val);
    }


    /**
     * 获取hashKey对应的所有键值
     * @param key 键
     * @return 对应的多个键值
     */
    public Map<Object, Object> hmget(String key) {
        return redisTemplate.opsForHash().entries(key);
    }


    /**
     * 判断hash表中是否有该项的值
     */
    public boolean hHasKey(String key,String filed) {
        return redisTemplate.opsForHash().hasKey(key,filed);
    }

    /**
     * 删除hash
     */
    public void hdel(String key,Object... filed) {
        redisTemplate.opsForHash().delete(key,filed);
    }
    /**
     * hash递增 如果不存在,就会创建一个 并把新增后的值返回
     *
     * @param key  键
     * @param filed 项
     * @param by   要增加几(大于0)
     */
    public double hincr(String key, String filed, long by) {
        return redisTemplate.opsForHash().increment(key, filed, by);
    }
    /**
     * hash递减
     *
     * @param key  键
     * @param filed 项
     * @param by   要减少记(小于0)
     */
    public double hdecr(String key, String filed, double by) {
        return redisTemplate.opsForHash().increment(key, filed, -by);
    }

    /**
     * 添加hash键值对
     */
    public void hset(String key,String filed,Object value) {
        redisTemplate.opsForHash().put(key,filed,value);
    }

    /**
     * 获取hash键值对
     */
    public Object hget(String key,String filed) {
        return redisTemplate.opsForHash().get(key,filed)==null?null:redisTemplate.opsForHash().get(key,filed);
    }

    /**
     * 定时任务将博客浏览次数从redis缓存写入数据库
     */
    @Scheduled(cron="* * 1  * * ? ")
    public void blogViewToDB() {
        System.out.println("开始从redis写入db");
        Map<Object, Object> blogView = hmget("blogView");
        for(Map.Entry entry:blogView.entrySet()) {
            blogMapper.addView(Long.parseLong(entry.getKey().toString()),Long.parseLong(entry.getValue().toString()));
            //写入完成删除缓存
            hdel("blogView",entry.getKey());
        }
    }
}
